package com.ep.thirdPlatformProject.system.aop;

import com.alibaba.fastjson.JSON;
import com.ep.thirdPlatformProject.dhg.entity.DhgCommonEmployeeEntity;
import com.ep.thirdPlatformProject.system.entity.SyncOARecordEntity;
import com.ep.thirdPlatformProject.system.enums.OASyncLogEnum;
import com.ep.thirdPlatformProject.system.exception.CustomException;
import com.ep.thirdPlatformProject.system.service.SyncOARecordService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtilsProperties;
import org.springframework.stereotype.Component;

import java.util.regex.Pattern;


@Component
@Aspect
@Slf4j
@RequiredArgsConstructor
public class SyncRecordAspect {

    private final SyncOARecordService recordService;

    private final SyncOARecordService syncOARecordService;

    @Pointcut("@annotation(com.ep.thirdPlatformProject.system.aop.SyncRecordLog)")
    public void logPointCut() {
    }


    @Around(value = "logPointCut()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        // 获取日志配置的基本信息
        MethodSignature signature = (MethodSignature) point.getSignature();
        SyncRecordLog annotation = signature.getMethod().getAnnotation(SyncRecordLog.class);
        OASyncLogEnum oaSyncLogEnum = annotation.logType();
        String methodName = signature.getMethod().getName();
        String params = JSON.toJSONString(point.getArgs());
        log.info("参数信息：{}", params);

        // 获取到对应的参数信息
        DhgCommonEmployeeEntity entity = JSON.parseObject(params, DhgCommonEmployeeEntity.class);

        try {
            Boolean hasRecord = syncOARecordService.findHasRecentRecordByCodeAndTime(entity.getEmpNo(), annotation.logType().getFormId(), annotation.dateLimit());

            if (hasRecord) {
                String message = entity.getEmpNo() + ":" + entity.getEmpName() +
                        (annotation.dateLimit() ? "近一个月" : "") +
                        "已经通过接口生成过申请单了";
                // 构建日志记录(新增失败日志，生成过单的书记依旧要记录下来，方便后续查看)
                SyncOARecordEntity record = buildRecord(oaSyncLogEnum, entity, params, message, methodName, false);

                // 保存日志记录
                recordService.insertOneRecord(record);
                throw new CustomException(message);
            }

            Object result;
            try {
                result = point.proceed();
                // 判断是否是纯粹的流程数字
                boolean isSuccess = Pattern.matches("^\\d+$", result.toString());
                // 构建日志记录
                SyncOARecordEntity record = buildRecord(oaSyncLogEnum, entity, params, result.toString(), methodName, isSuccess);

                // 保存日志记录
                recordService.insertOneRecord(record);

                return result; // 直接返回方法执行结果
            } catch (Exception ex) {
                // 构建日志记录
                SyncOARecordEntity record = buildRecord(oaSyncLogEnum, entity, params, ex.getMessage(), methodName, false);

                // 保存日志记录
                recordService.insertOneRecord(record);

                throw ex; // 让异常继续传播
            }
        } catch (Exception ex) {
            return "日志保存失败，可以忽略此异常："+ex.getMessage();
        }
    }


    /**
     * 建立记录
     *
     * @param oaSyncLogEnum 表单id
     * @param isSuccess     是否成功
     * @return {@link SyncOARecordEntity }
     */
    private SyncOARecordEntity buildRecord(OASyncLogEnum oaSyncLogEnum, DhgCommonEmployeeEntity employee,
                                           String params, String result, String methodName,
                                           Boolean isSuccess) {
        SyncOARecordEntity.SyncOARecordEntityBuilder builder = SyncOARecordEntity.builder();
        try (InetUtils inetUtils = new InetUtils(new InetUtilsProperties())) {

            String ipAddress = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
            builder = builder
                    .empNo(employee.getEmpNo())
                    .empName(employee.getEmpName())
                    .methodName(methodName)
                    .recordData(result)
                    .params(params)
                    .formId(oaSyncLogEnum.getFormId())
                    .formName(oaSyncLogEnum.getFormName())
                    .ipAddress(ipAddress)
                    .isSuccess(isSuccess);
        } catch (Exception e) {
            log.error(">>>>>>>>>>>ip错误:{}", e.getMessage());
        }

        return builder.build();
    }


}
